﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace WCF
{
   
    public class getData : IWCF
    {
        
        /// <summary>
        /// Returns a user when submiting userID
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public UserComposite GetUser(Guid ID)
        {
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    Users user = (from c in db.Users
                                  where c.USERID == ID
                                  select c).Single();
                    UserComposite UserC = new UserComposite();
                    UserC.UserID = user.USERID;
                    UserC.Username = user.AccontName;
                    UserC.Image = user.Image;
                    UserC.Firstname = user.Firstname;
                    UserC.Lastname = user.Lastname;
                    UserC.Gender = user.Gender;
                    UserC.Age = user.Age;
                    UserC.Information = user.Information;

                    return UserC;

                }
                catch
                {
                    return null;

                }

            }
        }
        /// <summary>
        /// Creates a user
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="Username"></param>
        /// <param name="Image"></param>
        /// <param name="Firstname"></param>
        /// <param name="Lastname"></param>
        /// <param name="Gender"></param>
        /// <param name="Age"></param>
        /// <param name="Information"></param>
        /// <returns></returns>
        public bool AddUser(Guid UserID, string Username, string Image, string Firstname, string Lastname, string Gender, int Age, string Information)
        {
            using (UsersEntities db = new UsersEntities())
            try{
            Users user = new Users();
            user.USERID = UserID;
            user.AccontName = Username;
            user.Image = Image;
            user.Firstname = Firstname;
            user.Lastname = Lastname;
            user.Gender = Gender;
            user.Age = Age;
            user.Information = Information;

            db.Users.AddObject(user);

            db.SaveChanges();
            return true;
            }
            catch{
                return false;
            }
        }
        /// <summary>
    /// Updates the requested users firstname
    /// </summary>
    /// <param name="ID"></param>
    /// <param name="firstname"></param>
    /// <returns></returns>
        public bool UpdateFirstname(Guid ID, string firstname)
        {
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    Users user = (from c in db.Users
                                  where c.USERID == ID
                                  select c).Single();
                    user.Firstname = firstname;
                    db.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;

                }

            }
        }
        /// <summary>
        /// Updates the requested users lastname
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="lastname"></param>
        /// <returns></returns>
        public bool UpdateLastname(Guid ID, string lastname)
        {
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    Users user = (from c in db.Users
                                  where c.USERID == ID
                                  select c).Single();
                    user.Lastname = lastname;
                    db.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;

                }

            }
        }
        /// <summary>
        /// Updates requested users age
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public bool UpdateAge(Guid ID, int age)
        {
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    Users user = (from c in db.Users
                                  where c.USERID == ID
                                  select c).Single();
                    user.Age = age;
                    db.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;

                }

            }
        }
        /// <summary>
        /// Updates requested users gender
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="gender"></param>
        /// <returns></returns>
        public bool UpdateGender(Guid ID, string gender)
        {
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    Users user = (from c in db.Users
                                  where c.USERID == ID
                                  select c).Single();
                    user.Gender = gender;
                    db.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;

                }

            }
        }
        /// <summary>
        /// Updates requested users information
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="info"></param>
        /// <returns></returns>
        public bool UpdateInformation(Guid ID, string info)
        {

            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    Users user = (from c in db.Users
                                  where c.USERID == ID
                                  select c).Single();
                    user.Information = info;
                    db.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;

                }

            }
        }
        /// <summary>
        /// Updates requested users image url
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="image"></param>
        /// <returns></returns>
        public bool UpdateImage(Guid ID, string image)
        {
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    Users user = (from c in db.Users
                                  where c.USERID == ID
                                  select c).Single();
                    user.Image = image;
                    db.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;

                }

            }
        }
        /// <summary>
        /// Returns a list of all users with a username
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public List<UserComposite> getUsersByUsername(string username)
        {
            List<UserComposite> usersC = new List<UserComposite>();
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    var users = (from u in db.Users
                                 where u.AccontName == username
                                 select u).ToList();
                    List<Users> us = (List<Users>)users;
                    foreach (Users user in us)
                    {
                        UserComposite UserC = new UserComposite();
                        UserC.UserID = user.USERID;
                        UserC.Username = user.AccontName;
                        UserC.Image = user.Image;
                        UserC.Firstname = user.Firstname;
                        UserC.Lastname = user.Lastname;
                        UserC.Gender = user.Gender;
                        UserC.Age = user.Age;
                        UserC.Information = user.Information;

                        usersC.Add(UserC);
                    }
                    return usersC;
                }
                catch
                {
                    return null;
                }
            }

        }
        /// <summary>
        /// Returns a list with all users with the requested firstname
        /// </summary>
        /// <param name="firstname"></param>
        /// <returns></returns>
        public List<UserComposite> getUsersByFirstname(string firstname)
        {
            List<UserComposite> usersC = new List<UserComposite>();
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    var users = (from u in db.Users
                                 where u.Firstname == firstname
                                 select u).ToList();
                    List<Users> us = (List<Users>)users;
                    foreach (Users user in us)
                    {
                        UserComposite UserC = new UserComposite();
                        UserC.UserID = user.USERID;
                        UserC.Username = user.AccontName;
                        UserC.Image = user.Image;
                        UserC.Firstname = user.Firstname;
                        UserC.Lastname = user.Lastname;
                        UserC.Gender = user.Gender;
                        UserC.Age = user.Age;
                        UserC.Information = user.Information;

                        usersC.Add(UserC);
                    }
                    return usersC;
                }
                catch
                {
                    return null;
                }
            }
        }
        /// <summary>
        /// Returns a list with all users with the requested lastname
        /// </summary>
        /// <param name="lastname"></param>
        /// <returns></returns>
        public List<UserComposite> getUsersByLastname(string lastname)
        {
            List<UserComposite> usersC = new List<UserComposite>();
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    var users = (from u in db.Users
                                 where u.Lastname == lastname
                                 select u).ToList();
                    List<Users> us = (List<Users>)users;
                    foreach (Users user in us)
                    {
                        UserComposite UserC = new UserComposite();
                        UserC.UserID = user.USERID;
                        UserC.Username = user.AccontName;
                        UserC.Image = user.Image;
                        UserC.Firstname = user.Firstname;
                        UserC.Lastname = user.Lastname;
                        UserC.Gender = user.Gender;
                        UserC.Age = user.Age;
                        UserC.Information = user.Information;

                        usersC.Add(UserC);
                    }
                    return usersC;
                }
                catch
                {
                    return null;
                }
            }
        }
        /// <summary>
        /// A bool statement that checks if two users are friends
        /// </summary>
        /// <param name="firstUserID"></param>
        /// <param name="secondUserID"></param>
        /// <returns></returns>
        public bool isFriends(Guid firstUserID, Guid secondUserID)
        {
            using (UsersEntities db = new UsersEntities())
            {
                try
                {
                    Friendship friends = (from u in db.Friendship
                                          where u.UserID == firstUserID
                                          && u.FriendID == secondUserID
                                          select u).Single();
                    FriendshipComposite friendsC = new FriendshipComposite();
                    friendsC.UserID = friends.UserID;
                    friendsC.FriendID = friends.FriendID;
                    friendsC.RelationshipID = friends.RelationshipID;
                    if (friendsC != null)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }

                }
                catch
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// Creates a new relationship between two user in the database
        /// Because of a faulty decision when creating the database we're stuck
        /// with using string nchar(10) instead of Guid for relationshipID.
        /// </summary>
        /// <param name="firstUserID"></param>
        /// <param name="secondUserID"></param>
        /// <returns></returns>
        public bool becomeFriends(Guid firstUserID, Guid secondUserID)
        {
            if (!(isFriends(firstUserID, secondUserID)))
                    {
            using (UsersEntities db = new UsersEntities())
                try
                {
                    Friendship friends = new Friendship();
                    friends.UserID = firstUserID;
                    friends.FriendID = secondUserID;

                    string friendshipstring = (firstUserID.ToString().Substring(0, 4)) + (secondUserID.ToString().Substring(0, 4));
                    friends.RelationshipID = friendshipstring;

                    db.Friendship.AddObject(friends);
                    db.SaveChanges();

                    return true;
                }
                catch
                {
                    return false;
                    }
            }
                    
            else
            {
                return true;
            }
        
        }
        /// <summary>
        /// Deletes the friendship relationship between two users
        /// </summary>
        /// <param name="firstUserID"></param>
        /// <param name="secondUserID"></param>
        /// <returns></returns>
        public bool deleteFriend(Guid firstUserID, Guid secondUserID)
        {
            {
                using (UsersEntities db = new UsersEntities())
                    try
                    {
                        Friendship friends = (from u in db.Friendship
                                              where u.UserID == firstUserID
                                              && u.FriendID == secondUserID
                                              select u).Single();
                        db.Friendship.DeleteObject(friends);
                        db.SaveChanges();
                        return true;
                    }
                    catch
                    {
                        return false;
                    }
            }
        }
        /// <summary>
        /// Returns all friends for one user
        /// </summary>
        /// <param name="loggedInUser"></param>
        /// <returns></returns>
        public List<UserComposite> getFriends(Guid loggedInUser)
        {
            List<UserComposite> friends = new List<UserComposite>();
             
             using (UsersEntities db = new UsersEntities())
                 try
                 {
                     var friendList = (from u in db.Friendship
                                where u.UserID == loggedInUser
                                select u.FriendID).ToList();
                    List<Guid> friendsID = (List<Guid>)friendList;
                     foreach (var friend in friendsID)
                     {
                         friends.Add
                             (GetUser(friend));
                     }
                 }
            catch{
                return null;
                     }

            return friends;
        }
        /// <summary>
        /// Creates a message and saves it
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool sendMessage(MessageComposite message)
        {
            
            using (UsersEntities db = new UsersEntities())
                try
                {
                    Message msg = new Message();
                    msg.MessageID = message.MessageID;
                    msg.Message1 = message.Message;
                    msg.Sentdate = message.Sentdate.ToString();
                    msg.Sender = message.Sender;
                    msg.Recepient = message.Recepient;
                    msg.Viewed = message.Viewed;

                    db.Message.AddObject(msg);
                    db.SaveChanges();
                    return true;
                }
                catch
                {
                    return false;
                }
           
        }
        /// <summary>
        /// Gets a specific message
        /// </summary>
        /// <param name="messageID"></param>
        /// <returns></returns>
        public MessageComposite getMessage(Guid messageID)
        {
            MessageComposite msg = new MessageComposite();
            using (UsersEntities db = new UsersEntities())
                try {
                    Message message = (from m in db.Message
                                  where m.MessageID == messageID
                                  select m).Single();
                    
                    msg.MessageID = message.MessageID;
                    msg.Message = message.Message1;
                    msg.Sentdate = message.Sentdate.ToString();
                    msg.Sender = message.Sender;
                    msg.Recepient = message.Recepient;
                    msg.Viewed = message.Viewed;
                    return msg;
                }
                catch {
                    return null;
                }
        }
        /// <summary>
        /// Gets a list with all messages for one user
        /// </summary>
        /// <param name="loggedInUser"></param>
        /// <returns></returns>
        public List<MessageComposite> getMessages(Guid loggedInUser)
        {
            List<MessageComposite> messagesC = new List<MessageComposite>();
            using(UsersEntities db = new UsersEntities())
                try
                {
                    var msgs = (from m in db.Message
                                where m.Recepient == loggedInUser
                                select m).ToList();
                    List<Message> messages = (List<Message>)msgs;

                    foreach (Message message in messages)
                    {
                        MessageComposite msg = new MessageComposite();
                        msg.MessageID = message.MessageID;
                        msg.Message = message.Message1;
                        msg.Sentdate = message.Sentdate.ToString();
                        msg.Sender = message.Sender;
                        msg.Recepient = message.Recepient;
                        msg.Viewed = message.Viewed;
                        messagesC.Add(msg);
                    }
                    return messagesC;
                }
                catch
                {
                    return null;
                }
            
            }
        /// <summary>
        /// A "count" statement that returns the amount of messages a user has
        /// </summary>
        /// <param name="loggedInUser"></param>
        /// <returns></returns>
        public int messageAmount(Guid loggedInUser)
        {
            int msgAmount = 0;
            
            using(UsersEntities db = new UsersEntities())
                try
                {
                    msgAmount = (from u in db.Message
                                 where u.Recepient == loggedInUser
                                 select u).Count();
                    return msgAmount;
                }
                catch
                {
                    return msgAmount;
                }
            
        }
        /// <summary>
        /// Returns all wallposts for one user
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<WallComposite> getWallPosts(Guid userID)
        {
            List<WallComposite> posts = new List<WallComposite>();
            using (UsersEntities db = new UsersEntities())
                try
                {
                    var dbList = (from p in db.Wall
                                     where p.Recepient == userID
                                     select p).ToList();
                   
                    List<Wall>dbPosts = (List<Wall>)dbList;
                    foreach (Wall post in dbPosts)
                    {
                        WallComposite postC = new WallComposite();
                        postC.MessageID = post.MessageID;
                        postC.Title = post.Title;
                        postC.Message = post.Message;
                        postC.SentDate = post.SentDate;
                        postC.Sender = post.Sender;
                        postC.Recepient = post.Recepient;

                        posts.Add(postC);
                    }
                    return posts;
                }
                catch
                {
                    return posts;
                }
        }
        /// <summary>
        /// Takes a wallpost and saves it
        /// </summary>
        /// <param name="postC"></param>
        /// <returns></returns>
        public bool postOnWall(WallComposite postC){
            
                    using (UsersEntities db = new UsersEntities())
                        try
                        {
                            Wall post = new Wall();
                            post.MessageID = postC.MessageID;
                            post.Message = postC.Message;
                            post.SentDate = postC.SentDate;
                            post.Sender = postC.Sender;
                            post.Recepient = postC.Recepient;
                            post.Title = postC.Title;

                            db.Wall.AddObject(post);
                            db.SaveChanges();
                            return true;
                        }
                        catch
                        {
                            return false;
                        }
                }
               
        }
    }

